﻿//统一文件为utf-8编码编译
#pragma execution_character_set("utf-8")
///////////////////////////////////////////////////////////////////////////
// 文件名:     qtcpsocketserver.h
// 描述:
// 作者:      颜磊
// 创建时间:   2024-06-08 23:42
///////////////////////////////////////////////////////////////////////////
#ifndef QTCPSOCKETSERVER_H
#define QTCPSOCKETSERVER_H

#include <QObject>
#include <QTcpServer>
#include <QTcpSocket>
#include <QThread>
#include <QTimer>
class QTcpSocketConnection;
class QTcpSocketListen;
/**
 * @brief The QTcpSocketServer class
 */
class QTcpSocketServer : public QThread
{
    Q_OBJECT
public:
    explicit QTcpSocketServer(QString address,uint16_t listenPort,QObject *parent = nullptr);
    ~QTcpSocketServer();
    void open();
    void close();
signals:
    void signal_recvData(uint64_t connectionId,QByteArray data);//收到数据
    void signal_joinConnection(uint64_t connectionId); //连接加入
    void signal_exitConnection(uint64_t connectionId); //连接退出

    void signal_openSocket();
    void signal_closeSocket();
private slots:
    void slot_openSocket();
    void slot_closeSocket();
public slots:
    void slot_openListen();
    void slot_closeListen();
    void slot_sendData(uint64_t connectionId,QByteArray data);//发送数据
    void slot_exitConnection(uint64_t connectionId); //连接退出
    void slot_joinConnection(qintptr handle); //监听到连接加入
private:
    QMap<uint64_t,QTcpSocketConnection*> connectionMap;
    uint64_t connectionId;
    uint64_t getConnectionId();

    QString address; //监听地址
    uint16_t listenPort; //tcpServer监听端口
    bool isOpen;
    QTimer listenTimer;
    QTcpSocketListen *tcpSocketListen; //tcpServer服务
protected:
    void run() override;
};
/**
 * @brief The QTcpSocketListen class
 */
class QTcpSocketListen : public QTcpServer
{
    Q_OBJECT
public:
    explicit QTcpSocketListen(QObject *parent = nullptr);
    ~QTcpSocketListen();
signals:
    void signal_incomingConnection(qintptr handle); //连接加入
protected:
    void incomingConnection(qintptr handle) override;
};

/**
 * @brief The QTcpSocketConnection class
 */
class QTcpSocketConnection : public QThread
{
    Q_OBJECT
public:
    explicit QTcpSocketConnection(uint64_t connectionId,qintptr socket,QObject *parent = nullptr);
    ~QTcpSocketConnection();
    void open();
    void close();
    void sendData(QByteArray data);
signals:
    void signal_exitConnection(uint64_t connectionId);
    void signal_recvData(uint64_t connectionId,QByteArray byteArray);
    void signal_sendData(QByteArray byteArray);

    void signal_openSocket();
    void signal_closeSocket();
private slots:
    void slot_tcpSocketReadyRead();
    void slot_tcpSocketDisconnected();

    void slot_openSocket();
    void slot_closeSocket();
public slots:
    void slot_sendData(QByteArray byteArray);
private:
    quint16 getSendPackId();
    void parsingFrameData(const QByteArray &byteArray); //解析数据帧
private:
    uint64_t connectionId;//连接ID
    qintptr socketPtr;
    bool isOpen;    //socket打开
    QTcpSocket *tcpSocket;
private:
    quint16 sendPackId;
    quint16 recvPackId;
    uint32_t nextFrameSerial; //下一帧序号
    QByteArray recvFrameTempData;
    QByteArray recvPackData; //临时接收数据
protected:
    void run() override;
};


#endif // QTCPSOCKETSERVER_H
